#include "env.h"       // 环境
// ################################################################
// ################################################################
// 自定义参数设置，本文件不存服务器：
// #define _RTC_  // 是否使用rtc芯片，不用芯片必须有wifi
// #define _SHOW_DEBUG_  // 是否显示DEBUG参数
// #define _SW01_  // 是否交换01字段
// #define _SW23_        // 是否交换23字段
// ################################################################
// ################################################################

// ################################################################
// ################################################################
// 管脚
#define LED_PIN 2     // D4 LED指示灯，正常时2s闪烁，连不上wifi时1s闪烁
#define RESET_PIN 0   // D3 FLASH，复位wifi按键，于板载flash键同
#define NIGHT_PIN 13  // D7 nigth mode (14-D5)，休眠模式，字段自动向下
// ################################################################
// ################################################################

// 使用的库：
// 1.NTPClient (修改过的)
// 2.Adafruit BusIO
// 3.Adafruit PWM Servo Driver Library
// 4.ESP8266TimerInterrupt
// 5.WIFIManager
// 6.uRTCLib

#include <NTPClient.h>  // 1.NTPClient (修改过的)
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>  // 3.Adafruit PWM Servo Driver Library 2.Adafruit BusIO
#include <EEPROM.h>

// ========================================================================================================
// wifi
#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>  // 5.WIFIManager

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "ntp.aliyun.com", 8 * 60 * 60, 30 * 60 * 1000);
// ========================================================================================================

// wifimanager can run in a blocking mode or a non blocking mode
// Be sure to know how to process loops with no delay() if using non blocking
bool wm_nonblocking = true;  // change to true to use non blocking

WiFiManager wm;                     // global wm instance
WiFiManagerParameter custom_field;  // global param ( for non blocking w params )

// --------------------------------------------------------------------------------------------------------
// These define's must be placed at the beginning before #include "ESP8266TimerInterrupt.h"
// _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
// Don't define _TIMERINTERRUPT_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
#define _TIMERINTERRUPT_LOGLEVEL_ 0
//
// Select a Timer Clock
#define USING_TIM_DIV1 false   // for shortest and most accurate timer
#define USING_TIM_DIV16 false  // for medium time and medium accurate timer
#define USING_TIM_DIV256 true  // for longest timer but least accurate. Default
//
#include "ESP8266TimerInterrupt.h"  // 4.ESP8266TimerInterrupt
//
#define TIMER_INTERVAL_MS 50  // 50ms
//
// Init ESP8266 timer 1
ESP8266Timer ITimer;
// --------------------------------------------------------------------------------------------------------

// RTC
#ifdef _RTC_
#include <uRTCLib.h>  // 6.uRTCLib
uRTCLib rtc(0x68);
#endif

// 默认地址 0x40
Adafruit_PWMServoDriver pwm0 = Adafruit_PWMServoDriver();
Adafruit_PWMServoDriver pwm1 = Adafruit_PWMServoDriver(0x41);

// 参数
#define DELAY_SEC 100  // 延时
#define OFFSET 10      // 微调

volatile char comchar;        // 串口字符命令
volatile bool click = false;  // 是否按键
bool wifi_ok = true;          // wifi正常

// 准备微调设置第几个数字的第几个字段偏移量，h向上显示状态
uint8_t h0 = 0;

volatile bool tosett = false;
volatile bool readrtc = false;
volatile bool readntp = false;

#define STATE_DOWN 0                // 状态: 装配状态
#define STATE_SHOW 1                // 状态: 正常显示时间
#define STATE_SETT 5                // 状态: 设置4*7字段角度
#define STATE_UPUP 6                // 状态: 设置4*7字段角度
volatile int mystate = STATE_DOWN;  // 状态: 开机时为装配状态，字段全部向下，20s后自动恢复显示时间

#include "vari.h"       // 变量
#include "func.h"       // 函数
#include "setupfunc.h"  // Setup函数
#include "time.h"       // time函数

// 定时中断子程序，50ms
void IRAM_ATTR TimerHandler() {
  static int i, k, j, l;
  static bool led;
  int m;

#ifndef _RTC_
  static int n;
  n++;
  if (n >= 20) {
    n = 0;  // 1s
    seco++;
    if (seco >= 60) {
      seco = 0;
      minu++;
      if (minu >= 60) {
        minu = 0;
        hour++;
        if (hour >= 24) {
          hour = 0;
          minu = 0;
          seco = 0;
        }
      }
    }
  }
#endif

  l++;
  if (l >= 40) {
    l = 0;
    readrtc = mystate == STATE_SHOW;
  }

  // 0.5s or 2s，显示LED灯
  i++;
  wifi_ok ? m = 40 : m = 10;
  if (i >= m) {
    i = 0;
    led = !led;
    digitalWrite(LED_PIN, led ? HIGH : LOW);
  }

  // 20s超时，状态回到显示时间初始状态
  k++;
  if (k >= 400) {
    k = 0;
    if (mystate != STATE_SETT) {
      if (digitalRead(NIGHT_PIN) == LOW) {
        comchar = 'g';
        click = true;
        Serial.println("Night coming...");
      } else {
        readrtc = true;
        num0 = 0;
        num1 = 0;
        num2 = 0;
        num3 = 0;
        mystate = STATE_SHOW;
        Serial.println("Timeout backto STATE_SHOW...");
      }
    }
  }

  // 1 hour
  j++;
  if (j >= 1200 * 60) {
    j = 0;
    readntp = true;
  }
}

void setup() {
  Serial.begin(115200);
  Serial.println("MySEGClock by xtbanban(88185785@qq.com)");

  pinMode(LED_PIN, OUTPUT);
  pinMode(NIGHT_PIN, INPUT_PULLUP);
  pinMode(RESET_PIN, INPUT_PULLUP);

  pwm0.begin();
  pwm0.setPWMFreq(50);  // 50HZ更新频率，相当于20ms的周期
  pwm1.begin();
  pwm1.setPWMFreq(50);

  EEPROM.begin(256);
  SET_DEFAULT = EEPROM.read(255);
  SetEeprom();

#ifdef _RTC_
  URTCLIB_WIRE.begin(4, 5);  // ESP8266 - RTC
#endif

  // mystate = STATE_DOWN;
  // SetSEGDown();  // 开机全部向下，20s后正常
  mystate = STATE_UPUP;
  SetSEGUpUp();

  ITimer.attachInterruptInterval(TIMER_INTERVAL_MS * 1000, TimerHandler);

  // ====================================================================
  if (wm_nonblocking) wm.setConfigPortalBlocking(false);
  //
  // test custom html(radio)
  const char* custom_radio_str = "<br/><label for='customfieldid'>Custom Field Label</label><br><input type='radio' name='customfieldid' value='1' checked> Show mode<br><input type='radio' name='customfieldid' value='2'> Set mode<br><br><input type='radio' name='customfieldid' value='3'> n<br><input type='radio' name='customfieldid' value='4'> <<br><input type='radio' name='customfieldid' value='5'> >";
  new (&custom_field) WiFiManagerParameter(custom_radio_str);  // custom html input
  //
  wm.addParameter(&custom_field);
  wm.setSaveParamsCallback(saveParamCallback);
  wm.setMinimumSignalQuality(10);
  wm.setSaveConfigCallback(saveConfigCallback);
  //
  std::vector<const char*> menu = { "wifi", "param", "sep" };
  wm.setMenu(menu);
  //
  wm.setClass("invert");
  //
  if (!wm.autoConnect("MySEGClock-WiFi")) {
    wifi_ok = false;
    Serial.println("WiFi not connect !!!");
  } else {
    wifi_ok = SetRTCTime();
  }
}

void saveConfigCallback() {
  Serial.println("Save config");
  wifi_ok = SetRTCTime();
}

String getParam(String name) {
  //read parameter from server, for customhmtl input
  String value;
  if (wm.server->hasArg(name)) {
    value = wm.server->arg(name);
  }
  return value;
}

void saveParamCallback() {
  String gp = getParam("customfieldid");
  Serial.println("[CALLBACK] saveParamCallback fired");
  Serial.println("PARAM customfieldid = " + gp);
  if (gp == String('1')) {
    num0 = 0;
    num1 = 0;
    num2 = 0;
    num3 = 0;
    mystate = STATE_SHOW;
  } else if (gp == String('2')) {
    tosett = true;
    mystate = STATE_SETT;
  } else if (gp == String('3')) {
    comchar = 'h';
    click = true;
  } else if (gp == String('4')) {
    comchar = '<';
    click = true;
  } else if (gp == String('5')) {
    comchar = '>';
    click = true;
  }
}

void checkResetButton() {
  if (digitalRead(RESET_PIN) == LOW) {
    delay(50);
    if (digitalRead(RESET_PIN) == LOW) {
      Serial.println("Reset Button Pressed");
      delay(3000);
      if (digitalRead(RESET_PIN) == LOW) {
        Serial.println("Reset Button Held");
        Serial.println("Erasing Config, restarting");
        wm.resetSettings();
        ESP.restart();
      }
    }
  }
}

void loop() {
  // avoid delays() in loop when non-blocking and other long running code
  if (wm_nonblocking) wm.process();
  checkResetButton();

  if (readntp) {
    readntp = false;
    if ((mystate > STATE_DOWN) && (mystate < STATE_SETT)) {
      wifi_ok = SetRTCTime();
    }
  }

  if (readrtc) {
    readrtc = false;
    //
#ifdef _RTC_
    // 取得rtc时间
    rtc.refresh();
    minu = rtc.minute();
    hour = rtc.hour();
    seco = rtc.second();
    Serial.print("Read RTC:");
#else
    Serial.print("Read MyRTC:");
#endif
    //
    Serial.print(hour, DEC);
    Serial.print(":");
    Serial.print(minu, DEC);
    Serial.print(":");
    Serial.print(seco, DEC);
    Serial.println("");
  }

  if ((mystate > STATE_DOWN) && (mystate < STATE_SETT)) {
    minu_0 = minu / 10 % 10 + 48;
    minu_1 = minu % 10 + 48;
    hour_0 = hour / 10 % 10 + 48;
    hour_1 = hour % 10 + 48;
    // 从个位开始逐个显示
    if (num1 != minu_1) {
      num1 = minu_1;
      set = 1;
      comchar = num1;
      click = true;
      delay(DELAY_SEC);
      Serial.print("show num1: ");
    } else if (num0 != minu_0) {
      num0 = minu_0;
      set = 0;
      comchar = num0;
      click = true;
      delay(DELAY_SEC);
      Serial.print("show num0: ");
    } else if (num3 != hour_1) {
      num3 = hour_1;
      set = 3;
      comchar = num3;
      click = true;
      delay(DELAY_SEC);
      Serial.print("show num3: ");
    } else if (num2 != hour_0) {
      num2 = hour_0;
      set = 2;
      comchar = num2;
      click = true;
      delay(DELAY_SEC);
      Serial.print("show num2: ");
    }
  }

  if (tosett) {
    tosett = false;
    h0 = -1;
    // 全部上升
    Set0Seg0124(SEG_0_0, true);
    Set0Seg0124(SEG_0_1, true);
    Set0Seg0124(SEG_0_2, true);
    Set0Seg0124(SEG_0_4, true);
    Set0Seg356(true, true, true);
    delay(DELAY_SEC);
    Set1Seg0124(SEG_1_0, true);
    Set1Seg0124(SEG_1_1, true);
    Set1Seg0124(SEG_1_2, true);
    Set1Seg0124(SEG_1_4, true);
    Set1Seg356(true, true, true);
    delay(DELAY_SEC);
    Set2Seg0124(SEG_2_0, true);
    Set2Seg0124(SEG_2_1, true);
    Set2Seg0124(SEG_2_2, true);
    Set2Seg0124(SEG_2_4, true);
    Set2Seg356(true, true, true);
    delay(DELAY_SEC);
    Set3Seg0124(SEG_3_0, true);
    Set3Seg0124(SEG_3_1, true);
    Set3Seg0124(SEG_3_2, true);
    Set3Seg0124(SEG_3_4, true);
    Set3Seg356(true, true, true);
    delay(10 * DELAY_SEC);
  }

  // 循环从串口读到数据，或者key置位
  while (Serial.available() > 0 || click) {
    if (click) {
      click = false;
    } else {
      comchar = Serial.read();
    }
    Serial.println(comchar);

    switch (comchar) {
      // 根据set变量，选择4位之一显示0到9
      case '0':
        SetSegnum0();
        break;
      case '1':
        SetSegnum1();
        break;
      case '2':
        SetSegnum2();
        break;
      case '3':
        SetSegnum3();
        break;
      case '4':
        SetSegnum4();
        break;
      case '5':
        SetSegnum5();
        break;
      case '6':
        SetSegnum6();
        break;
      case '7':
        SetSegnum7();
        break;
      case '8':
        SetSegnum8();
        break;
      case '9':
        SetSegnum9();
        break;

      // 字段向外一点
      case '<':
        switch (h0) {
          case 0:
            OFFSET_UP_0_0 = OFFSET_UP_0_0 + OFFSET;
            break;
          case 1:
            OFFSET_UP_0_1 = OFFSET_UP_0_1 + OFFSET;
            break;
          case 2:
            OFFSET_UP_0_2 = OFFSET_UP_0_2 - OFFSET;
            break;
          case 3:
            OFFSET_UP_0_3 = OFFSET_UP_0_3 - OFFSET;
            break;
          case 4:
            OFFSET_UP_0_4 = OFFSET_UP_0_4 + OFFSET;
            break;
          case 5:
            OFFSET_UP_0_5 = OFFSET_UP_0_5 - OFFSET;
            break;
          case 6:
            OFFSET_UP_0_6 = OFFSET_UP_0_6 + OFFSET;
            break;
          // next seg
          case 0 + 7:
            OFFSET_UP_1_0 = OFFSET_UP_1_0 + OFFSET;
            break;
          case 1 + 7:
            OFFSET_UP_1_1 = OFFSET_UP_1_1 + OFFSET;
            break;
          case 2 + 7:
            OFFSET_UP_1_2 = OFFSET_UP_1_2 - OFFSET;
            break;
          case 3 + 7:
            OFFSET_UP_1_3 = OFFSET_UP_1_3 - OFFSET;
            break;
          case 4 + 7:
            OFFSET_UP_1_4 = OFFSET_UP_1_4 + OFFSET;
            break;
          case 5 + 7:
            OFFSET_UP_1_5 = OFFSET_UP_1_5 - OFFSET;
            break;
          case 6 + 7:
            OFFSET_UP_1_6 = OFFSET_UP_1_6 + OFFSET;
            break;
          // next seg
          case 0 + 7 + 7:
            OFFSET_UP_2_0 = OFFSET_UP_2_0 + OFFSET;
            break;
          case 1 + 7 + 7:
            OFFSET_UP_2_1 = OFFSET_UP_2_1 + OFFSET;
            break;
          case 2 + 7 + 7:
            OFFSET_UP_2_2 = OFFSET_UP_2_2 - OFFSET;
            break;
          case 3 + 7 + 7:
            OFFSET_UP_2_3 = OFFSET_UP_2_3 - OFFSET;
            break;
          case 4 + 7 + 7:
            OFFSET_UP_2_4 = OFFSET_UP_2_4 + OFFSET;
            break;
          case 5 + 7 + 7:
            OFFSET_UP_2_5 = OFFSET_UP_2_5 - OFFSET;
            break;
          case 6 + 7 + 7:
            OFFSET_UP_2_6 = OFFSET_UP_2_6 + OFFSET;
            break;
          // next seg
          case 0 + 7 + 7 + 7:
            OFFSET_UP_3_0 = OFFSET_UP_3_0 + OFFSET;
            break;
          case 1 + 7 + 7 + 7:
            OFFSET_UP_3_1 = OFFSET_UP_3_1 + OFFSET;
            break;
          case 2 + 7 + 7 + 7:
            OFFSET_UP_3_2 = OFFSET_UP_3_2 - OFFSET;
            break;
          case 3 + 7 + 7 + 7:
            OFFSET_UP_3_3 = OFFSET_UP_3_3 - OFFSET;
            break;
          case 4 + 7 + 7 + 7:
            OFFSET_UP_3_4 = OFFSET_UP_3_4 + OFFSET;
            break;
          case 5 + 7 + 7 + 7:
            OFFSET_UP_3_5 = OFFSET_UP_3_5 - OFFSET;
            break;
          case 6 + 7 + 7 + 7:
            OFFSET_UP_3_6 = OFFSET_UP_3_6 + OFFSET;
            break;
        }
        SaveEeprom();
        if (h0 < 7) {
          set = 0;
        } else if (h0 < 7 + 7) {
          set = 1;
        } else if (h0 < 7 + 7 + 7) {
          set = 2;
        } else {
          set = 3;
        }
        comchar = '8';
        click = true;
        Serial.print("SAVE_SEGOFF:");
        Serial.println(h0);
        break;

      // 字段向内一点
      case '>':
        switch (h0) {
          case 0:
            OFFSET_UP_0_0 = OFFSET_UP_0_0 - OFFSET;
            break;
          case 1:
            OFFSET_UP_0_1 = OFFSET_UP_0_1 - OFFSET;
            break;
          case 2:
            OFFSET_UP_0_2 = OFFSET_UP_0_2 + OFFSET;
            break;
          case 3:
            OFFSET_UP_0_3 = OFFSET_UP_0_3 + OFFSET;
            break;
          case 4:
            OFFSET_UP_0_4 = OFFSET_UP_0_4 - OFFSET;
            break;
          case 5:
            OFFSET_UP_0_5 = OFFSET_UP_0_5 + OFFSET;
            break;
          case 6:
            OFFSET_UP_0_6 = OFFSET_UP_0_6 - OFFSET;
            break;
          // next seg
          case 0 + 7:
            OFFSET_UP_1_0 = OFFSET_UP_1_0 - OFFSET;
            break;
          case 1 + 7:
            OFFSET_UP_1_1 = OFFSET_UP_1_1 - OFFSET;
            break;
          case 2 + 7:
            OFFSET_UP_1_2 = OFFSET_UP_1_2 + OFFSET;
            break;
          case 3 + 7:
            OFFSET_UP_1_3 = OFFSET_UP_1_3 + OFFSET;
            break;
          case 4 + 7:
            OFFSET_UP_1_4 = OFFSET_UP_1_4 - OFFSET;
            break;
          case 5 + 7:
            OFFSET_UP_1_5 = OFFSET_UP_1_5 + OFFSET;
            break;
          case 6 + 7:
            OFFSET_UP_1_6 = OFFSET_UP_1_6 - OFFSET;
            break;
          // next seg
          case 0 + 7 + 7:
            OFFSET_UP_2_0 = OFFSET_UP_2_0 - OFFSET;
            break;
          case 1 + 7 + 7:
            OFFSET_UP_2_1 = OFFSET_UP_2_1 - OFFSET;
            break;
          case 2 + 7 + 7:
            OFFSET_UP_2_2 = OFFSET_UP_2_2 + OFFSET;
            break;
          case 3 + 7 + 7:
            OFFSET_UP_2_3 = OFFSET_UP_2_3 + OFFSET;
            break;
          case 4 + 7 + 7:
            OFFSET_UP_2_4 = OFFSET_UP_2_4 - OFFSET;
            break;
          case 5 + 7 + 7:
            OFFSET_UP_2_5 = OFFSET_UP_2_5 + OFFSET;
            break;
          case 6 + 7 + 7:
            OFFSET_UP_2_6 = OFFSET_UP_2_6 - OFFSET;
            break;
          // next seg
          case 0 + 7 + 7 + 7:
            OFFSET_UP_3_0 = OFFSET_UP_3_0 - OFFSET;
            break;
          case 1 + 7 + 7 + 7:
            OFFSET_UP_3_1 = OFFSET_UP_3_1 - OFFSET;
            break;
          case 2 + 7 + 7 + 7:
            OFFSET_UP_3_2 = OFFSET_UP_3_2 + OFFSET;
            break;
          case 3 + 7 + 7 + 7:
            OFFSET_UP_3_3 = OFFSET_UP_3_3 + OFFSET;
            break;
          case 4 + 7 + 7 + 7:
            OFFSET_UP_3_4 = OFFSET_UP_3_4 - OFFSET;
            break;
          case 5 + 7 + 7 + 7:
            OFFSET_UP_3_5 = OFFSET_UP_3_5 + OFFSET;
            break;
          case 6 + 7 + 7 + 7:
            OFFSET_UP_3_6 = OFFSET_UP_3_6 - OFFSET;
            break;
        }
        SaveEeprom();
        if (h0 < 7) {
          set = 0;
        } else if (h0 < 7 + 7) {
          set = 1;
        } else if (h0 < 7 + 7 + 7) {
          set = 2;
        } else {
          set = 3;
        }
        comchar = '8';
        click = true;
        Serial.print("SAVE_SEGOFF:");
        Serial.println(h0);
        break;

      // 向上显示状态下，选择需要设置位置的字段
      case 'h':
        mystate = STATE_SETT;  // 强制进入设置状态
        // 下一个字段
        h0++;
        if (h0 > 6 + 7 + 7 + 7) {
          h0 = -1;  // 设置结束了，继续设置
          Serial.print("Setting again...");
          break;
        } else {
          Serial.print("SET_SEGOFF:");
          Serial.println(h0);
        }
        // 要设置的字段摇一下
        if (h0 == 0) {
          pwm0.setPWM(SEG_0_0, 0, SERVO_135_A);
        } else if (h0 == 1) {
          pwm0.setPWM(SEG_0_1, 0, SERVO_135_A);
        } else if (h0 == 2) {
          pwm0.setPWM(SEG_0_2, 0, SERVO_135_R);
        } else if (h0 == 3) {
          pwm0.setPWM(SEG_0_3, 0, SERVO_135_R);
        } else if (h0 == 4) {
          pwm0.setPWM(SEG_0_4, 0, SERVO_135_R);
        } else if (h0 == 5) {
          pwm0.setPWM(SEG_0_5, 0, SERVO_135_A);
        } else if (h0 == 6) {
          pwm0.setPWM(SEG_0_3, 0, SERVO_90_R);
          pwm0.setPWM(SEG_0_5, 0, SERVO_90_A);
          delay(5 * DELAY_SEC);
          pwm0.setPWM(SEG_0_6, 0, SERVO_135_A);
          pwm0.setPWM(SEG_0_R, 0, SERVO_135_R);
          delay(5 * DELAY_SEC);
          pwm0.setPWM(SEG_0_6, 0, SERVO_180_A);
        } else if (h0 == 0 + 7) {
          // 下一个字了
          pwm0.setPWM(SEG_1_0, 0, SERVO_135_A);
        } else if (h0 == 1 + 7) {
          pwm0.setPWM(SEG_1_1, 0, SERVO_135_A);
        } else if (h0 == 2 + 7) {
          pwm0.setPWM(SEG_1_2, 0, SERVO_135_R);
        } else if (h0 == 3 + 7) {
          pwm0.setPWM(SEG_1_3, 0, SERVO_135_R);
        } else if (h0 == 4 + 7) {
          pwm0.setPWM(SEG_1_4, 0, SERVO_135_R);
        } else if (h0 == 5 + 7) {
          pwm0.setPWM(SEG_1_5, 0, SERVO_135_A);
        } else if (h0 == 6 + 7) {
          pwm0.setPWM(SEG_1_3, 0, SERVO_90_R);
          pwm0.setPWM(SEG_1_5, 0, SERVO_90_A);
          delay(5 * DELAY_SEC);
          pwm0.setPWM(SEG_1_6, 0, SERVO_135_A);
          pwm0.setPWM(SEG_1_R, 0, SERVO_135_R);
          delay(5 * DELAY_SEC);
          pwm0.setPWM(SEG_1_6, 0, SERVO_180_A);
        } else if (h0 == 0 + 7 + 7) {
          // 再下一个字了
          pwm1.setPWM(SEG_2_0, 0, SERVO_135_A);
        } else if (h0 == 1 + 7 + 7) {
          pwm1.setPWM(SEG_2_1, 0, SERVO_135_A);
        } else if (h0 == 2 + 7 + 7) {
          pwm1.setPWM(2, 0, SERVO_135_R);
        } else if (h0 == 3 + 7 + 7) {
          pwm1.setPWM(SEG_2_3, 0, SERVO_135_R);
        } else if (h0 == 4 + 7 + 7) {
          pwm1.setPWM(SEG_2_4, 0, SERVO_135_R);
        } else if (h0 == 5 + 7 + 7) {
          pwm1.setPWM(SEG_2_5, 0, SERVO_135_A);
        } else if (h0 == 6 + 7 + 7) {
          pwm1.setPWM(SEG_2_3, 0, SERVO_90_R);
          pwm1.setPWM(SEG_2_5, 0, SERVO_90_A);
          delay(5 * DELAY_SEC);
          pwm1.setPWM(SEG_2_6, 0, SERVO_135_A);
          pwm1.setPWM(SEG_2_R, 0, SERVO_135_R);
          delay(5 * DELAY_SEC);
          pwm1.setPWM(SEG_2_6, 0, SERVO_180_A);
        } else if (h0 == 0 + 7 + 7 + 7) {
          // 再下一个字了
          pwm1.setPWM(SEG_3_0, 0, SERVO_135_A);
        } else if (h0 == 1 + 7 + 7 + 7) {
          pwm1.setPWM(SEG_3_1, 0, SERVO_135_A);
        } else if (h0 == 2 + 7 + 7 + 7) {
          pwm1.setPWM(2, 0, SERVO_135_R);
        } else if (h0 == 3 + 7 + 7 + 7) {
          pwm1.setPWM(SEG_3_3, 0, SERVO_135_R);
        } else if (h0 == 4 + 7 + 7 + 7) {
          pwm1.setPWM(SEG_3_4, 0, SERVO_135_R);
        } else if (h0 == 5 + 7 + 7 + 7) {
          pwm1.setPWM(SEG_3_5, 0, SERVO_135_A);
        } else if (h0 == 6 + 7 + 7 + 7) {
          pwm1.setPWM(SEG_3_3, 0, SERVO_90_R);
          pwm1.setPWM(SEG_3_5, 0, SERVO_90_A);
          delay(5 * DELAY_SEC);
          pwm1.setPWM(SEG_3_6, 0, SERVO_135_A);
          pwm1.setPWM(SEG_3_R, 0, SERVO_135_R);
          delay(5 * DELAY_SEC);
          pwm1.setPWM(SEG_3_6, 0, SERVO_180_A);
        }
        // 延时长一点
        delay(5 * DELAY_SEC);
        // 再全部上升
        Set0Seg0124(SEG_0_0, true);
        Set0Seg0124(SEG_0_1, true);
        Set0Seg0124(SEG_0_2, true);
        Set0Seg0124(SEG_0_4, true);
        Set0Seg356(true, true, true);
        delay(DELAY_SEC);
        Set1Seg0124(SEG_1_0, true);
        Set1Seg0124(SEG_1_1, true);
        Set1Seg0124(SEG_1_2, true);
        Set1Seg0124(SEG_1_4, true);
        Set1Seg356(true, true, true);
        delay(DELAY_SEC);
        Set2Seg0124(SEG_2_0, true);
        Set2Seg0124(SEG_2_1, true);
        Set2Seg0124(SEG_2_2, true);
        Set2Seg0124(SEG_2_4, true);
        Set2Seg356(true, true, true);
        delay(DELAY_SEC);
        Set3Seg0124(SEG_3_0, true);
        Set3Seg0124(SEG_3_1, true);
        Set3Seg0124(SEG_3_2, true);
        Set3Seg0124(SEG_3_4, true);
        Set3Seg356(true, true, true);
        delay(DELAY_SEC);
        break;

      case 'z':
        SET_DEFAULT = 0;
        SetEeprom();
        h0 = -1;
        Serial.println("Set EEprom default...");
        break;

      case 'g':
        mystate = STATE_DOWN;
        readrtc = false;
        SetSEGDown();
        Serial.println("All down...");
        break;
    }

#ifdef _SHOW_DEGUB_
    // 显示参数mystate
    Serial.print("mystate:");
    Serial.print(mystate, DEC);
    Serial.println(" ");
    Serial.println("---------------------");

    Serial.print("num0:");
    Serial.print(num0 - 48);
    Serial.println(" ");

    Serial.print("OFF:");
    Serial.print(OFFSET_UP_0_0, DEC);
    Serial.print(" ");
    Serial.print(OFFSET_UP_0_1, DEC);
    Serial.print(" ");
    Serial.print(OFFSET_UP_0_2, DEC);
    Serial.print(" ");
    Serial.print(OFFSET_UP_0_3, DEC);
    Serial.print(" ");
    Serial.print(OFFSET_UP_0_4, DEC);
    Serial.print(" ");
    Serial.print(OFFSET_UP_0_5, DEC);
    Serial.print(" ");
    Serial.print(OFFSET_UP_0_6, DEC);
    Serial.print(" ");
    Serial.print(OFFSET_UP_0_6, DEC);
    Serial.println(" ");

    Serial.print("GET:");
    Serial.print(pwm0.getPWM(SEG_0_0, true), DEC);
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_0_1, true), DEC);
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_0_2, true), DEC);
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_0_3, true), DEC);
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_0_4, true), DEC);
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_0_5, true), DEC);
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_0_6, true), DEC);
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_0_R, true), DEC);
    Serial.println(" ");

    Serial.print("U&D:");
    Serial.print(pwm0.getPWM(SEG_0_0, true) > SERVO_90_A ? "up" : "down");
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_0_1, true) > SERVO_90_A ? "up" : "down");
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_0_2, true) < SERVO_90_R ? "up" : "down");
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_0_3, true) < SERVO_90_R ? "up" : "down");
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_0_4, true) < SERVO_90_R ? "up" : "down");
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_0_5, true) > SERVO_90_A ? "up" : "down");
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_0_6, true) > SERVO_90_A ? "up" : "down");
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_0_R, true) > SERVO_90_R ? "up" : "down");
    Serial.println(" ");

    Serial.print("num1:");
    Serial.print(num1 - 48);
    Serial.println(" ");

    Serial.print("OFF:");
    Serial.print(OFFSET_UP_1_0, DEC);
    Serial.print(" ");
    Serial.print(OFFSET_UP_1_1, DEC);
    Serial.print(" ");
    Serial.print(OFFSET_UP_1_2, DEC);
    Serial.print(" ");
    Serial.print(OFFSET_UP_1_3, DEC);
    Serial.print(" ");
    Serial.print(OFFSET_UP_1_4, DEC);
    Serial.print(" ");
    Serial.print(OFFSET_UP_1_5, DEC);
    Serial.print(" ");
    Serial.print(OFFSET_UP_1_6, DEC);
    Serial.print(" ");
    Serial.print(OFFSET_UP_1_6, DEC);
    Serial.println(" ");

    Serial.print("GET:");
    Serial.print(pwm0.getPWM(SEG_1_0, true), DEC);
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_1_1, true), DEC);
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_1_2, true), DEC);
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_1_3, true), DEC);
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_1_4, true), DEC);
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_1_5, true), DEC);
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_1_6, true), DEC);
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_1_R, true), DEC);
    Serial.println(" ");

    Serial.print("U&D:");
    Serial.print(pwm0.getPWM(SEG_1_0, true) > SERVO_90_A ? "up" : "down");
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_1_1, true) > SERVO_90_A ? "up" : "down");
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_1_2, true) < SERVO_90_R ? "up" : "down");
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_1_3, true) < SERVO_90_R ? "up" : "down");
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_1_4, true) < SERVO_90_R ? "up" : "down");
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_1_5, true) > SERVO_90_A ? "up" : "down");
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_1_6, true) > SERVO_90_A ? "up" : "down");
    Serial.print(" ");
    Serial.print(pwm0.getPWM(SEG_1_R, true) > SERVO_90_R ? "up" : "down");
    Serial.println(" ");
    Serial.println("---------------------");
#endif
  }
}
